
package com.da.landlord;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Filter;
import org.hibernate.annotations.Index;
import org.hibernate.annotations.Where;

import com.googlecode.cswish.annotation.cm;
import com.ra.landlord.LandlordOwner;
import com.ra.landlord.LandlordOwnerUser;

/**
 * 房间
 * @author Perter.Z
 *
 */
@Entity
@Table(name="da_daroom")
public class DaRoom implements LandlordOwner {
	
	@cm("已出租")
	public final static int RENT_STATE_RENT = 0;
	
	@cm("未出租")
	public final static int RENT_STATE_UNRENT = 1;
	
	@cm("预定")	
	public final static int RENT_STATE_BOOK = 2;
	
	@cm("转租")	
	public final static int RENT_STATE_SUBLET = 3;
	
	@cm("已出租")
	public final static int RENT_STATE_HIDDEN = 4;

	private Integer id;
	
	@cm("房间所对应的合约")
	private List<DaAgreement> agreements;
	
	@cm("表示一个有效合约,冗余字段")
	private DaAgreement agreement;
	
	@cm("名称")
	private String name;
	
	@cm("房间编号")
	private String roomNum;
	
	@cm("面积")
	private BigDecimal area;
	
	@cm("房间朝向")
	private Integer orientation;
	
	@cm("租借状态")	// (0:已出租；1：未出租；2：预定；3：转租；4：隐藏)
	private Integer rentState;
	
	@cm("所属房源")
	private DaSuite suite;
	
	@cm("付款方式  押几") //实际收费按合同收费
	private Integer depositNum;
	
	@cm("付款方式  付几") // 实际收费按合同收费 交租日期=起租日期+付几月  -提前多天
	private Integer payNum;
	
	@cm("房间类型") //0.主卧  1 .次卧 2.客卧
	private Integer roomType;
	
	@cm("可住人数")
	private Integer checkInNum;
	
	@cm("性别要求 0 男 1女 2无要求")
	private Integer sex;
	
	@cm("租金  元/月")
	private BigDecimal rentPay;
	
	@cm("押金 元")
	private BigDecimal deposit;
	
	@cm("房间设施")
	private DaRoomItem roomItem;
	
	@cm("所属房东")
	private LandlordOwnerUser landlordUser;
	
	@cm("房间所对应的帐单")
	private List<DaChargeBill> chargeBills;
	
	@cm("是否已收租")
	private Boolean chargeSate;
	
	@cm("对应的收费项 --->未缴费的")
	private List<DaChargeItem> chargeItems;
	
	@cm("对应的收费项 --->已确认的收费项")
	private List<DaChargeItem> chargeOrders;
	
	@cm("对应的收费项 --->抄表记录的所有收费项")
	private List<DaChargeItem> chargeItemsForMeter;
	
	@cm("对应的收费项--->不带where")
	private List<DaChargeItem> chargeItemsWithNoConditon;
	
	@cm("针对房间的独立费用项配置")
	private List<DaFeeRule> feeRules;
	
	//transient
	@cm("上次抄表")
	private DaMeter lastMeter;
	
	@cm("上上次抄表")
	private DaMeter lastLastMeter;
	
	// transient, 指定某一计费规则下， 该规则的本次读表数据和上次读表数据
	@cm("本次抄表")
	private DaMeter currentMeter;	
	
	//transient 是否已缴费
	private Boolean hasPaid;
	
	@Transient	
	public DaMeter getLastMeter() {
		return lastMeter;
	}

	public void setLastMeter(DaMeter lastMeter) {
		this.lastMeter = lastMeter;
	}
	@Transient
	public DaMeter getLastLastMeter() {
		return lastLastMeter;
	}

	public void setLastLastMeter(DaMeter lastLastMeter) {
		this.lastLastMeter = lastLastMeter;
	}
	@Transient
	public DaMeter getCurrentMeter() {
		return currentMeter;
	}

	public void setCurrentMeter(DaMeter currentMeter) {
		this.currentMeter = currentMeter;
	}

	/**
	 * 针对房间的独立费用规则
	 * @return
	 */
	@OneToMany(mappedBy="room" ,cascade=CascadeType.ALL)
	@Where(clause="state=1")
	public List<DaFeeRule> getFeeRules() {
		return feeRules;
	}
	
	public void setFeeRules(List<DaFeeRule> feeRules) {
		this.feeRules = feeRules;
	}
	
	
	//入住条件限制  见CheckInRequirement
	@ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	public DaRoomItem getRoomItem() {
		return roomItem;
	}

	public void setRoomItem(DaRoomItem roomItem) {
		this.roomItem = roomItem;
	}

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Index(name = "idx_daroom_name")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public BigDecimal getArea() {
		return area;
	}

	public void setArea(BigDecimal area) {
		this.area = area;
	}

	public Integer getOrientation() {
		return orientation;
	}

	public void setOrientation(Integer orientation) {
		this.orientation = orientation;
	}

	public Integer getRentState() {
		return rentState;
	}

	public void setRentState(Integer rentState) {
		this.rentState = rentState;
	}

	public String getRoomNum() {
		return roomNum;
	}

	public void setRoomNum(String roomNum) {
		this.roomNum = roomNum;
	}
	
	

	public Integer getDepositNum() {
		return depositNum;
	}

	public void setDepositNum(Integer depositNum) {
		this.depositNum = depositNum;
	}

	public Integer getPayNum() {
		return payNum;
	}

	public void setPayNum(Integer payNum) {
		this.payNum = payNum;
	}

	public Integer getRoomType() {
		return roomType;
	}

	public void setRoomType(Integer roomType) {
		this.roomType = roomType;
	}

	public Integer getCheckInNum() {
		return checkInNum;
	}

	public void setCheckInNum(Integer checkInNum) {
		this.checkInNum = checkInNum;
	}

	public BigDecimal getRentPay() {
		return rentPay;
	}

	public void setRentPay(BigDecimal rentPay) {
		this.rentPay = rentPay;
	}

	public Integer getSex() {
		return sex;
	}

	public void setSex(Integer sex) {
		this.sex = sex;
	}

	@ManyToOne(fetch=FetchType.LAZY)
	public DaSuite getSuite() {
		return suite;
	}

	public void setSuite(DaSuite suite) {
		this.suite = suite;
	}

	@ManyToOne(fetch=FetchType.LAZY)
	public LandlordOwnerUser getLandlordUser() {
		return landlordUser;
	}

	public void setLandlordUser(LandlordOwnerUser landlordUser) {
		this.landlordUser = landlordUser;
	}

	

	@OneToMany(mappedBy="room" ,cascade = {CascadeType.ALL}, orphanRemoval=true)
	@OrderBy("id desc")
	public List<DaChargeBill> getChargeBills() {
		return chargeBills;
	}

	public void setChargeBills(List<DaChargeBill> chargeBills) {
		this.chargeBills = chargeBills;
	}

	//只作删除，不作其他处理 用于判断是否已交租
	@OneToMany(mappedBy="room" ,cascade = {CascadeType.REMOVE})
	@Where(clause = "status=0")
	public List<DaChargeItem> getChargeItems() {
		return chargeItems;
	}

	public void setChargeItems(List<DaChargeItem> chargeItems) {
		this.chargeItems = chargeItems;
	}

	
	@OneToMany(mappedBy="room" ,cascade = {CascadeType.PERSIST})
	@Where(clause = "chargeType=2")
	@OrderBy("dateEndRecv desc")
	public List<DaChargeItem> getChargeItemsForMeter() {
		return chargeItemsForMeter;
	}

	public void setChargeItemsForMeter(List<DaChargeItem> chargeItemsForMeter) {
		this.chargeItemsForMeter = chargeItemsForMeter;
	}

	@OneToMany(mappedBy="room", fetch=FetchType.LAZY,
			cascade = {CascadeType.ALL}, orphanRemoval=true)
	public List<DaAgreement> getAgreements() {
		return agreements;
	}
	
	public void setAgreements(List<DaAgreement> agreements) {
		this.agreements = agreements;
	}

	/**
	 * 一个房子只能指向一个有效合约
	 * @return
	 */
	@ManyToOne(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
	public DaAgreement getAgreement() {
//		if( this.agreements!=null ){
//			for (DaAgreement daAgreement : agreements) {
//				if(daAgreement.getAgreementState().equals(0)){
//					return daAgreement;
//				}
//			}
//		}
		return agreement;
	}

	public void setAgreement(DaAgreement agreement) {
		this.agreement = agreement;
	}

	@Transient
	//@QLFormula(value=":qlFormulaForChargeSate", isColumn=false)
	public Boolean getChargeSate() {
		//true表示有收费项  false表示没有收费项
		if (this.chargeSate == null && this.chargeItems != null) {
			if (this.chargeItems.size() > 0 ){
				this.chargeSate = true;
			}else{
				this.chargeSate = false;
			}
		}
		return chargeSate;
	}
	
	public static String qlFormulaForAgreementState(Map<String, Object> model) {
		Object agreementState = model.get("agreementState");
		if (agreementState != null) {
			return "agreementState=0";
		}
		return "";
	}
	
	public static String qlFormulaForChargeSate(Map<String, Object> model) {
		Object chargeSate = model.get("chargeSate");
		if (chargeSate != null) {
			if ("true".equals(chargeSate) || Boolean.TRUE.equals(chargeSate)) {
				return "chargeItems.size > 0";
			} else if ("false".equals(chargeSate) || Boolean.FALSE.equals(chargeSate))  {
				return "chargeItems.size = 0";
			}
		}
		return "";
	}
	
	public void setChargeSate(Boolean chargeSate) {
		this.chargeSate = chargeSate;
	}

	@OneToMany(mappedBy="room" ,cascade = {CascadeType.REFRESH})
	@Where(clause = "status=2")
	public List<DaChargeItem> getChargeOrders() {
		return chargeOrders;
	}

	public void setChargeOrders(List<DaChargeItem> chargeOrders) {
		this.chargeOrders = chargeOrders;
	}

	@OneToMany(fetch = FetchType.LAZY, mappedBy="room")
	public List<DaChargeItem> getChargeItemsWithNoConditon() {
		return chargeItemsWithNoConditon;
	}

	public void setChargeItemsWithNoConditon(List<DaChargeItem> chargeItemsWithNoConditon) {
		this.chargeItemsWithNoConditon = chargeItemsWithNoConditon;
	}

	public BigDecimal getDeposit() {
		return deposit;
	}

	public void setDeposit(BigDecimal deposit) {
		this.deposit = deposit;
	}

	@Transient
	public Boolean getHasPaid() {
		return hasPaid;
	}

	public void setHasPaid(Boolean hasPaid) {
		this.hasPaid = hasPaid;
	}
	
}
